home *** CD-ROM | disk | FTP | other *** search
/ Super PC 26 / Super PC 26 (Shareware).iso / spc / util / fractint / source / prompts1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-27  |  68.4 KB  |  2,377 lines

  1. /*
  2.     Various routines that prompt for things.
  3. */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #ifndef XFRACT
  10. #include <dos.h>
  11. #elif !defined(__386BSD__)
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/dir.h>
  15. #endif
  16. #ifdef __TURBOC__
  17. #include <alloc.h>
  18. #elif !defined(__386BSD__)
  19. #include <malloc.h>
  20. #endif
  21.  
  22. #ifdef __hpux
  23. #include <sys/param.h>
  24. #define getwd(a) getcwd(a,MAXPATHLEN)
  25. #endif
  26.  
  27. #include "fractint.h"
  28. #include "fractype.h"
  29. #include "helpdefs.h"
  30. #include "prototyp.h"
  31.  
  32. /* Routines used in prompts2.c */
  33.  
  34.     int prompt_checkkey(int curkey);
  35.     long get_file_entry(int,char *,char *,char *,char *);
  36.  
  37. /* Routines in this module    */
  38.  
  39. int prompt_valuestring(char *buf,struct fullscreenvalues *val);
  40. static    int input_field_list(int attr,char *fld,int vlen,char **list,int llen,
  41.                  int row,int col,int (*checkkey)(int));
  42. static    int select_fracttype(int t);
  43. static    int sel_fractype_help(int curkey, int choice);
  44.     int select_type_params(int newfractype,int oldfractype);
  45.           void set_default_parms(void);
  46. static    long gfe_choose_entry(int,char *,char *,char *);
  47. static    int check_gfe_key(int curkey,int choice);
  48. static    void load_entry_text(FILE *entfile,char far *buf,int maxlines);
  49. static    void format_parmfile_line(int,char *);
  50. static    int get_light_params(void );
  51. static    int check_mapfile(void );
  52. static    int get_funny_glasses_params(void );
  53.  
  54. /* fullscreen_choice options */
  55. #define CHOICEHELP    4
  56.  
  57. #define GETFORMULA 0
  58. #define GETLSYS    1
  59. #define GETIFS       2
  60. #define GETPARM    3
  61.  
  62. static char funnyglasses_map_name[16];
  63. char ifsmask[13]     = {"*.ifs"};
  64. char formmask[13]    = {"*.frm"};
  65. char lsysmask[13]    = {"*.l"};
  66. char Glasses1Map[] = "glasses1.map";
  67. char MAP_name[80] = "";
  68. int  mapset = 0;
  69. int julibrot;   /* flag for julibrot */
  70.  
  71. /* --------------------------------------------------------------------- */
  72.  
  73. int promptfkeys;
  74.  
  75. int fullscreen_prompt(    /* full-screen prompting routine */
  76.     char far *hdg,        /* heading, lines separated by \n */
  77.     int numprompts,     /* there are this many prompts (max) */
  78.     char far **prompts,     /* array of prompting pointers */
  79.     struct fullscreenvalues *values, /* array of values */
  80.     int fkeymask,        /* bit n on if Fn to cause return */
  81.     char far *extrainfo    /* extra info box to display, \n separated */
  82.     )
  83. {
  84.    char far *hdgscan;
  85.    int titlelines,titlewidth,titlerow;
  86.    int maxpromptwidth,maxfldwidth,maxcomment;
  87.    int boxrow,boxlines;
  88.    int boxcol,boxwidth;
  89.    int extralines,extrawidth,extrarow;
  90.    int instrrow;
  91.    int promptrow,promptcol,valuecol;
  92.    int curchoice;
  93.    int done, i, j;
  94.    int anyinput;
  95.    int savelookatmouse;
  96.    int curtype, curlen;
  97.    char buf[81];
  98. #ifndef XFRACT
  99. static FCODE instr1[]  = {"Use " UPARR " and " DNARR " to select values to change"};
  100. static FCODE instr2a[]  = {"Type in replacement value for selected field"};
  101. static FCODE instr2b[]  = {"Use " LTARR " or " RTARR " to change value of selected field"};
  102. #else
  103. /* Some compilers don't accept "a" "b", so we have to fill in UPARR ourself.  */
  104. static char far instr1[]  = {"Use up(K) and down(J) to select values to change"};
  105. static char far instr2a[]  = {"Type in replacement value for selected field"};
  106. static char far instr2b[]  = {"Use left(H) or right(L) to change value of selected field"};
  107. #endif
  108. static FCODE instr3a[] = {"Press ENTER when finished (or ESCAPE to back out)"};
  109. static FCODE instr3b[] = {"Press ENTER when finished, ESCAPE to back out, or F1 for help"};
  110. static FCODE instr0a[] = {"No changeable parameters; press ENTER to exit"};
  111. static FCODE instr0b[] = {"No changeable parameters; press ENTER to exit, ESCAPE to back out, F1 for help"};
  112. /*   if (numprompts <= 0) { */    /* ?? nothing to do! */
  113. /*      return(0); */
  114. /*      } */
  115.    savelookatmouse = lookatmouse;
  116.    lookatmouse = 0;
  117.    promptfkeys = fkeymask;
  118.    helptitle();                /* clear screen, display title line  */
  119.    setattr(1,0,C_PROMPT_BKGRD,24*80);  /* init rest of screen to background */
  120.  
  121.    hdgscan = hdg;               /* count title lines, find widest */
  122.    i = titlewidth = 0;
  123.    titlelines = 1;
  124.    while (*hdgscan) {
  125.       if (*(hdgscan++) == '\n') {
  126.      ++titlelines;
  127.      i = -1;
  128.      }
  129.       if (++i > titlewidth)
  130.      titlewidth = i;
  131.       }
  132.    extralines = extrawidth = i = 0;
  133.    if ((hdgscan = extrainfo) != 0)
  134.       if (*hdgscan == 0)
  135.      extrainfo = NULL;
  136.       else { /* count extra lines, find widest */
  137.      extralines = 3;
  138.      while (*hdgscan) {
  139.         if (*(hdgscan++) == '\n') {
  140.            if (extralines + numprompts + titlelines >= 20) {
  141.            *hdgscan = 0; /* full screen, cut off here */
  142.            break;
  143.            }
  144.            ++extralines;
  145.            i = -1;
  146.            }
  147.         if (++i > extrawidth)
  148.            extrawidth = i;
  149.         }
  150.      }
  151.  
  152.    /* work out vertical positioning */
  153.    i = numprompts + titlelines + extralines + 3; /* total rows required */
  154.    j = (25 - i) / 2;               /* top row of it all when centered */
  155.    j -= j / 4;                   /* higher is better if lots extra */
  156.    boxlines = numprompts;
  157.    titlerow = 1 + j;
  158.    promptrow = boxrow = titlerow + titlelines;
  159.    if (titlerow > 2) {               /* room for blank between title & box? */
  160.       --titlerow;
  161.       --boxrow;
  162.       ++boxlines;
  163.       }
  164.    instrrow = boxrow+boxlines;
  165.    if (instrrow + 3 + extralines < 25) {
  166.       ++boxlines;    /* blank at bottom of box */
  167.       ++instrrow;
  168.       if (instrrow + 3 + extralines < 25)
  169.      ++instrrow; /* blank before instructions */
  170.       }
  171.    extrarow = instrrow + 2;
  172.    if (numprompts > 1) /* 3 instructions lines */
  173.       ++extrarow;
  174.    if (extrarow + extralines < 25)
  175.       ++extrarow;
  176.  
  177.    /* work out horizontal positioning */
  178.    maxfldwidth = maxpromptwidth = maxcomment = anyinput = 0;
  179.    for (i = 0; i < numprompts; i++) {
  180.       if (values[i].type == 'y') {
  181.      static char *noyes[2] = {s_no,s_yes};
  182.      values[i].type = 'l';
  183.      values[i].uval.ch.vlen = 3;
  184.      values[i].uval.ch.list = noyes;
  185.      values[i].uval.ch.llen = 2;
  186.      }
  187.       j = far_strlen(prompts[i]);
  188.       if (values[i].type == '*') {
  189.      if (j > maxcomment)     maxcomment = j;
  190.      }
  191.       else {
  192.          anyinput = 1;
  193.      if (j > maxpromptwidth) maxpromptwidth = j;
  194.      j = prompt_valuestring(buf,&values[i]);
  195.      if (j > maxfldwidth)     maxfldwidth = j;
  196.      }
  197.       }
  198.    boxwidth = maxpromptwidth + maxfldwidth + 2;
  199.    if (maxcomment > boxwidth) boxwidth = maxcomment;
  200.    if ((boxwidth += 4) > 80) boxwidth = 80;
  201.    boxcol = (80 - boxwidth) / 2;       /* center the box */
  202.    promptcol = boxcol + 2;
  203.    valuecol = boxcol + boxwidth - maxfldwidth - 2;
  204.    if (boxwidth <= 76) {           /* make margin a bit wider if we can */
  205.       boxwidth += 2;
  206.       --boxcol;
  207.       }
  208.    if ((j = titlewidth) < extrawidth)
  209.       j = extrawidth;
  210.    if ((i = j + 4 - boxwidth) > 0) {   /* expand box for title/extra */
  211.       if (boxwidth + i > 80)
  212.      i = 80 - boxwidth;
  213.       boxwidth += i;
  214.       boxcol -= i / 2;
  215.       }
  216.    i = (90 - boxwidth) / 20;
  217.    boxcol    -= i;
  218.    promptcol -= i;
  219.    valuecol  -= i;
  220.  
  221.    /* display box heading */
  222.    for (i = titlerow; i < boxrow; ++i)
  223.       setattr(i,boxcol,C_PROMPT_HI,boxwidth);
  224.    textcbase = boxcol + (boxwidth - titlewidth) / 2;
  225.    putstring(titlerow,0,C_PROMPT_HI,hdg);
  226.  
  227.    /* display extra info */
  228.    if (extrainfo) {
  229. #ifndef XFRACT
  230. #define S1 '\xC4'
  231. #define S2 "\xC0"
  232. #define S3 "\xD9"
  233. #define S4 "\xB3"
  234. #define S5 "\xDA"
  235. #define S6 "\xBF"
  236. #else
  237. #define S1 '-'
  238. #define S2 "+" /* ll corner */
  239. #define S3 "+" /* lr corner */
  240. #define S4 "|"
  241. #define S5 "+" /* ul corner */
  242. #define S6 "+" /* ur corner */
  243. #endif
  244.       memset(buf,S1,80); buf[boxwidth-2] = 0;
  245.       textcbase = boxcol + 1;
  246.       putstring(extrarow,0,C_PROMPT_BKGRD,buf);
  247.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,buf);
  248.       --textcbase;
  249.       putstring(extrarow,0,C_PROMPT_BKGRD,S5);
  250.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S2);
  251.       textcbase += boxwidth - 1;
  252.       putstring(extrarow,0,C_PROMPT_BKGRD,S6);
  253.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S3);
  254.       textcbase = boxcol;
  255.       for (i = 1; i < extralines-1; ++i) {
  256.          putstring(extrarow+i,0,C_PROMPT_BKGRD,S4);
  257.          putstring(extrarow+i,boxwidth-1,C_PROMPT_BKGRD,S4);
  258.      }
  259.       textcbase += (boxwidth - extrawidth) / 2;
  260.       putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
  261.       }
  262.    textcbase = 0;
  263.  
  264.    /* display empty box */
  265.    for (i = 0; i < boxlines; ++i)
  266.       setattr(boxrow+i,boxcol,C_PROMPT_LO,boxwidth);
  267.  
  268.    /* display initial values */
  269.    for (i = 0; i < numprompts; i++) {
  270.       putstring(promptrow+i, promptcol, C_PROMPT_LO, prompts[i]);
  271.       prompt_valuestring(buf,&values[i]);
  272.       putstring(promptrow+i, valuecol, C_PROMPT_LO, buf);
  273.       }
  274.  
  275.    if (!anyinput) {
  276.       putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  277.         (helpmode > 0) ? instr0b : instr0a);
  278.       movecursor(25,80);
  279.       for(;;) {
  280.         while (!keypressed()) { }
  281.         done = getakey();
  282.         switch(done) {
  283.            case ESC:
  284.               done = -1;
  285.            case ENTER:
  286.            case ENTER_2:
  287.               goto fullscreen_exit;
  288.            case F2:
  289.            case F3:
  290.            case F4:
  291.            case F5:
  292.            case F6:
  293.            case F7:
  294.            case F8:
  295.            case F9:
  296.            case F10:
  297.               if (promptfkeys & (1<<(done+1-F1)) )
  298.                  goto fullscreen_exit;
  299.            }
  300.         }
  301.       }
  302.  
  303.  
  304.    /* display footing */
  305.    if (numprompts > 1)
  306.       putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,instr1);
  307.    putstringcenter(instrrow+1,0,80,C_PROMPT_BKGRD,
  308.      (helpmode > 0) ? instr3b : instr3a);
  309.  
  310.    curchoice = done = 0;
  311.    while (values[curchoice].type == '*') ++curchoice;
  312.  
  313.    while (!done) {
  314.  
  315.       curtype = values[curchoice].type;
  316.       curlen = prompt_valuestring(buf,&values[curchoice]);
  317.       putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  318.               (curtype == 'l') ? instr2b : instr2a);
  319.       putstring(promptrow+curchoice,promptcol,C_PROMPT_HI,prompts[curchoice]);
  320.  
  321.       if (curtype == 'l') {
  322.      i = input_field_list(
  323.         C_PROMPT_CHOOSE, buf, curlen,
  324.         values[curchoice].uval.ch.list, values[curchoice].uval.ch.llen,
  325.         promptrow+curchoice,valuecol, prompt_checkkey);
  326.      for (j = 0; j < values[curchoice].uval.ch.llen; ++j)
  327.         if (strcmp(buf,values[curchoice].uval.ch.list[j]) == 0) break;
  328.      values[curchoice].uval.ch.val = j;
  329.      }
  330.       else {
  331.      j = 0;
  332.      if (curtype == 'i') j = 3;
  333.      if (curtype == 'L') j = 3;
  334.      if (curtype == 'd') j = 5;
  335.      if (curtype == 'D') j = 7;
  336.      if (curtype == 'f') j = 1;
  337.      i = input_field(j, C_PROMPT_INPUT, buf, curlen,
  338.         promptrow+curchoice,valuecol,prompt_checkkey);
  339.      switch (values[curchoice].type) {
  340.         case 'd':
  341.         case 'D':
  342.            values[curchoice].uval.dval = atof(buf);
  343.            break;
  344.         case 'f':
  345.            values[curchoice].uval.dval = atof(buf);
  346.            roundfloatd(&values[curchoice].uval.dval);
  347.            break;
  348.         case 'i':
  349.            values[curchoice].uval.ival = atoi(buf);
  350.            break;
  351.         case 'L':
  352.            values[curchoice].uval.Lval = atol(buf);
  353.            break;
  354.         case 's':
  355.            strncpy(values[curchoice].uval.sval,buf,16);
  356.            break;
  357.         default: /* assume 0x100+n */
  358.            far_strcpy(values[curchoice].uval.sbuf,buf);
  359.         }
  360.      }
  361.  
  362.       putstring(promptrow+curchoice,promptcol,C_PROMPT_LO,prompts[curchoice]);
  363.       j = strlen(buf);
  364.       memset(&buf[j],' ',80-j); buf[curlen] = 0;
  365.       putstring(promptrow+curchoice, valuecol, C_PROMPT_LO,  buf);
  366.  
  367.       switch(i) {
  368.      case 0:  /* enter  */
  369.         done = 13;
  370.         break;
  371.      case -1: /* escape */
  372.      case F2:
  373.      case F3:
  374.      case F4:
  375.      case F5:
  376.      case F6:
  377.      case F7:
  378.      case F8:
  379.      case F9:
  380.      case F10:
  381.         done = i;
  382.         break;
  383.      case PAGE_UP:
  384.         curchoice = -1;
  385.      case DOWN_ARROW:
  386.      case DOWN_ARROW_2:
  387.         do {
  388.            if (++curchoice >= numprompts) curchoice = 0;
  389.            } while (values[curchoice].type == '*');
  390.         break;
  391.      case PAGE_DOWN:
  392.         curchoice = numprompts;
  393.      case UP_ARROW:
  394.      case UP_ARROW_2:
  395.         do {
  396.            if (--curchoice < 0) curchoice = numprompts - 1;
  397.            } while (values[curchoice].type == '*');
  398.         break;
  399.      }
  400.       }
  401.  
  402. fullscreen_exit:
  403.    movecursor(25,80);
  404.    lookatmouse = savelookatmouse;
  405.    return(done);
  406. }
  407.  
  408. int prompt_valuestring(char *buf,struct fullscreenvalues *val)
  409. {  /* format value into buf, return field width */
  410.    int i,ret;
  411.    switch (val->type) {
  412.       case 'd':
  413.      ret = 20;
  414.      i = 16;    /* cellular needs 16 (was 15)*/
  415.      for(;;) {
  416.         sprintf(buf,"%.*g",i,val->uval.dval);
  417.         if ((int)strlen(buf) <= ret) break;
  418.         --i;
  419.         }
  420.      break;
  421.       case 'D':
  422.      if (val->uval.dval<0) { /* We have to round the right way */
  423.          sprintf(buf,"%ld",(long)(val->uval.dval-.5));
  424.      }
  425.      else {
  426.          sprintf(buf,"%ld",(long)(val->uval.dval+.5));
  427.      }
  428.      ret = 20;
  429.      break;
  430.       case 'f':
  431.      sprintf(buf,"%.7g",val->uval.dval);
  432.      ret = 14;
  433.      break;
  434.       case 'i':
  435.      sprintf(buf,"%d",val->uval.ival);
  436.      ret = 6;
  437.      break;
  438.       case 'L':
  439.      sprintf(buf,"%ld",val->uval.Lval);
  440.      ret = 10;
  441.      break;
  442.       case '*':
  443.      *buf = (char)(ret = 0);
  444.      break;
  445.       case 's':
  446.      strncpy(buf,val->uval.sval,16);
  447.      buf[15] = 0;
  448.      ret = 15;
  449.      break;
  450.       case 'l':
  451.      strcpy(buf,val->uval.ch.list[val->uval.ch.val]);
  452.      ret = val->uval.ch.vlen;
  453.      break;
  454.       default: /* assume 0x100+n */
  455.      far_strcpy(buf,val->uval.sbuf);
  456.      ret = val->type & 0xff;
  457.       }
  458.    return ret;
  459. }
  460.  
  461. int prompt_checkkey(int curkey)
  462. {
  463.    switch(curkey) {
  464.       case PAGE_UP:
  465.       case DOWN_ARROW:
  466.       case DOWN_ARROW_2:
  467.       case PAGE_DOWN:
  468.       case UP_ARROW:
  469.       case UP_ARROW_2:
  470.      return(curkey);
  471.       case F2:
  472.       case F3:
  473.       case F4:
  474.       case F5:
  475.       case F6:
  476.       case F7:
  477.       case F8:
  478.       case F9:
  479.       case F10:
  480.      if (promptfkeys & (1<<(curkey+1-F1)) )
  481.         return(curkey);
  482.       }
  483.    return(0);
  484. }
  485.  
  486. static int input_field_list(
  487.     int attr,          /* display attribute */
  488.     char *fld,          /* display form field value */
  489.     int vlen,          /* field length */
  490.     char **list,          /* list of values */
  491.     int llen,          /* number of entries in list */
  492.     int row,          /* display row */
  493.     int col,          /* display column */
  494.     int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  495.     )
  496. {
  497.    int initval,curval;
  498.    char buf[81];
  499.    int curkey;
  500.    int i, j;
  501.    int ret,savelookatmouse;
  502.    savelookatmouse = lookatmouse;
  503.    lookatmouse = 0;
  504.    for (initval = 0; initval < llen; ++initval)
  505.       if (strcmp(fld,list[initval]) == 0) break;
  506.    if (initval >= llen) initval = 0;
  507.    curval = initval;
  508.    ret = -1;
  509.    for(;;) {
  510.       strcpy(buf,list[curval]);
  511.       i = strlen(buf);
  512.       while (i < vlen)
  513.      buf[i++] = ' ';
  514.       buf[vlen] = 0;
  515.       putstring(row,col,attr,buf);
  516.       curkey = keycursor(row,col); /* get a keystroke */
  517.       switch (curkey) {
  518.      case ENTER:
  519.      case ENTER_2:
  520.         ret = 0;
  521.         goto inpfldl_end;
  522.      case ESC:
  523.         goto inpfldl_end;
  524.      case RIGHT_ARROW:
  525.      case RIGHT_ARROW_2:
  526.         if (++curval >= llen)
  527.            curval = 0;
  528.         break;
  529.      case LEFT_ARROW:
  530.      case LEFT_ARROW_2:
  531.         if (--curval < 0)
  532.            curval = llen - 1;
  533.         break;
  534.      case F5:
  535.         curval = initval;
  536.         break;
  537.      default:
  538.             if (nonalpha(curkey)) {
  539.            if (checkkey && (ret = (*checkkey)(curkey)) != 0)
  540.           goto inpfldl_end;
  541.            break;                     /* non alphanum char */
  542.            }
  543.         j = curval;
  544.         for (i = 0; i < llen; ++i) {
  545.            if (++j >= llen)
  546.           j = 0;
  547.            if ((*list[j] & 0xdf) == (curkey & 0xdf)) {
  548.           curval = j;
  549.           break;
  550.           }
  551.            }
  552.      }
  553.       }
  554. inpfldl_end:
  555.    strcpy(fld,list[curval]);
  556.    lookatmouse = savelookatmouse;
  557.    return(ret);
  558. }
  559.  
  560.  
  561. /* --------------------------------------------------------------------- */
  562.  
  563. /* MCP 7-7-91, This is static code, but not called anywhere */
  564. #ifdef DELETE_UNUSED_CODE
  565.  
  566. /* compare for sort of type table */
  567. static int compare(const VOIDPTR i, const VOIDPTR j)
  568. {
  569.    return(strcmp(fractalspecific[(int)*((BYTE*)i)].name,
  570.            fractalspecific[(int)*((BYTE*)j)].name));
  571. }
  572.  
  573. /* --------------------------------------------------------------------- */
  574.  
  575. static void clear_line(int row, int start, int stop, int color) /* clear part of a line */
  576. {
  577.    int col;
  578.    for(col=start;col<= stop;col++)
  579.       putstring(row,col,color," ");
  580. }
  581.  
  582. #endif
  583.  
  584. /* --------------------------------------------------------------------- */
  585.  
  586. int get_fracttype()        /* prompt for and select fractal type */
  587. {
  588.    int done,i,oldfractype,t;
  589.    done = -1;
  590.    oldfractype = fractype;
  591.    for(;;) {
  592.       if ((t = select_fracttype(fractype)) < 0)
  593.      break;
  594.       if ((i = select_type_params(t, fractype)) == 0) { /* ok, all done */
  595.      done = 0;
  596.      break;
  597.      }
  598.       if (i > 0) /* can't return to prior image anymore */
  599.      done = 1;
  600.       }
  601.    if (done < 0)
  602.       fractype = oldfractype;
  603.    curfractalspecific = &fractalspecific[fractype];
  604.    return(done);
  605. }
  606.  
  607. struct FT_CHOICE {
  608.       char name[15];
  609.       int  num;
  610.       };
  611. static struct FT_CHOICE far **ft_choices; /* for sel_fractype_help subrtn */
  612.  
  613. static int select_fracttype(int t) /* subrtn of get_fracttype, separated */
  614.                    /* so that storage gets freed up     */
  615. {
  616.    static FCODE head1[] = {"Select a Fractal Type"};
  617.    static FCODE head2[] = {"Select Orbit Algorithm for Julibrot"};
  618.    static FCODE o_instr[] = {"Press F2 for a description of the highlighted type"};
  619.    char instr[sizeof(o_instr)];
  620.    char head[40];
  621.    int oldhelpmode;
  622.    int numtypes, done;
  623.    int i, j;
  624. #define MAXFTYPES 200
  625.    char tname[40];
  626.    struct FT_CHOICE far *choices[MAXFTYPES];
  627.    int attributes[MAXFTYPES];
  628.  
  629.    /* steal existing array for "choices" */
  630.    choices[0] = (struct FT_CHOICE far *)boxy;
  631.    attributes[0] = 1;
  632.    for (i = 1; i < MAXFTYPES; ++i) {
  633.       choices[i] = choices[i-1] + 1;
  634.       attributes[i] = 1;
  635.       }
  636.    ft_choices = &choices[0];
  637.  
  638.    /* setup context sensitive help */
  639.    oldhelpmode = helpmode;
  640.    helpmode = HELPFRACTALS;
  641.    far_strcpy(instr,o_instr);
  642.    if(julibrot)
  643.       far_strcpy(head,head2);
  644.    else
  645.       far_strcpy(head,head1);    
  646.    if (t == IFS3D) t = IFS;
  647.    i = j = -1;
  648.    while(fractalspecific[++i].name) {
  649.       if(julibrot)
  650.     if (!((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*'))
  651.        continue;
  652.       if (fractalspecific[i].name[0] == '*')
  653.      continue;
  654.       far_strcpy(choices[++j]->name,fractalspecific[i].name);
  655.       choices[j]->name[14] = 0; /* safety */
  656.       choices[j]->num = i;    /* remember where the real item is */
  657.       }
  658.    numtypes = j + 1;
  659.    shell_sort(choices,numtypes,sizeof(char far *),lccompare); /* sort list */
  660.    j = 0;
  661.    for (i = 0; i < numtypes; ++i) /* find starting choice in sorted list */
  662.       if (choices[i]->num == t || choices[i]->num == fractalspecific[t].tofloat)
  663.      j = i;
  664.  
  665.    tname[0] = 0;
  666.    done = fullscreen_choice(CHOICEHELP+8,head,NULL,instr,numtypes,
  667.          (char far *far*)choices,attributes,0,0,0,j,NULL,tname,NULL,sel_fractype_help);
  668.    if (done >= 0)
  669.       done = choices[done]->num;
  670.    helpmode = oldhelpmode;
  671.    return(done);
  672. }
  673.  
  674. static int sel_fractype_help(int curkey,int choice)
  675. {
  676.    int oldhelpmode;
  677.    if (curkey == F2) {
  678.       oldhelpmode = helpmode;
  679.       helpmode = fractalspecific[(*(ft_choices+choice))->num].helptext;
  680.       help(0);
  681.       helpmode = oldhelpmode;
  682.       }
  683.    return(0);
  684. }
  685.  
  686. int select_type_params(    /* prompt for new fractal type parameters */
  687.     int newfractype,    /* new fractal type */
  688.     int oldfractype     /* previous fractal type */
  689.     )
  690. {
  691.    int ret,oldhelpmode;
  692.  
  693.    oldhelpmode = helpmode;
  694. sel_type_restart:
  695.    ret = 0;
  696.    fractype = newfractype;
  697.    curfractalspecific = &fractalspecific[fractype];
  698.  
  699.    if (fractype == LSYSTEM) {
  700.       helpmode = HT_LSYS;
  701.       if (get_file_entry(GETLSYS,"L-System",lsysmask,LFileName,LName) < 0) {
  702.      ret = 1;
  703.      goto sel_type_exit;
  704.      }
  705.       }
  706.    if (fractype == FORMULA || fractype == FFORMULA) {
  707.       helpmode = HT_FORMULA;
  708.       if (get_file_entry(GETFORMULA,"Formula",formmask,FormFileName,FormName) < 0) {
  709.      ret = 1;
  710.      goto sel_type_exit;
  711.      }
  712.       }
  713.    if (fractype == IFS || fractype == IFS3D) {
  714.       helpmode = HT_IFS;
  715.       if (get_file_entry(GETIFS,"IFS",ifsmask,IFSFileName,IFSName) < 0) {
  716.     ret = 1;
  717.     goto sel_type_exit;
  718.     }
  719.       }
  720.  
  721. /* Added the following to accommodate fn bifurcations.  JCO 7/2/92 */
  722.    if(((fractype == BIFURCATION) || (fractype == LBIFURCATION)) &&
  723.      !((oldfractype == BIFURCATION) || (oldfractype == LBIFURCATION)))
  724.         set_trig_array(0,s_ident);
  725.    if(((fractype == BIFSTEWART) || (fractype == LBIFSTEWART)) &&
  726.      !((oldfractype == BIFSTEWART) || (oldfractype == LBIFSTEWART)))
  727.         set_trig_array(0,s_ident);
  728.    if(((fractype == BIFLAMBDA) || (fractype == LBIFLAMBDA)) &&
  729.      !((oldfractype == BIFLAMBDA) || (oldfractype == LBIFLAMBDA)))
  730.         set_trig_array(0,s_ident);
  731.    if(((fractype == BIFEQSINPI) || (fractype == LBIFEQSINPI)) &&
  732.      !((oldfractype == BIFEQSINPI) || (oldfractype == LBIFEQSINPI)))
  733.         set_trig_array(0,s_sin);
  734.    if(((fractype == BIFADSINPI) || (fractype == LBIFADSINPI)) &&
  735.      !((oldfractype == BIFADSINPI) || (oldfractype == LBIFADSINPI)))
  736.         set_trig_array(0,s_sin);
  737.  
  738.    set_default_parms();
  739.  
  740.    if (get_fract_params(0) < 0)
  741.       if (fractype == FORMULA || fractype == FFORMULA ||
  742.           fractype == IFS || fractype == IFS3D ||
  743.           fractype == LSYSTEM)
  744.          goto sel_type_restart;
  745.       else
  746.          ret = 1;
  747.    else {
  748.       if (newfractype != oldfractype) {
  749.      invert = 0;
  750.      inversion[0] = inversion[1] = inversion[2] = 0;
  751.      }
  752.       }
  753.  
  754. sel_type_exit:
  755.    helpmode = oldhelpmode;
  756.    return(ret);
  757.  
  758. }
  759.  
  760. void set_default_parms()
  761. {
  762.    int i,extra;
  763.    xxmin = curfractalspecific->xmin;
  764.    xxmax = curfractalspecific->xmax;
  765.    yymin = curfractalspecific->ymin;
  766.    yymax = curfractalspecific->ymax;
  767.    xx3rd = xxmin;
  768.    yy3rd = yymin;
  769.    
  770.    if (viewcrop && finalaspectratio != screenaspect)
  771.       aspectratio_crop(screenaspect,finalaspectratio);
  772.    for (i = 0; i < 4; i++) {
  773.       param[i] = curfractalspecific->paramvalue[i];
  774.       if (fractype != CELLULAR && fractype != FROTH && fractype != FROTHFP)
  775.          roundfloatd(¶m[i]);   /* don't round cellular or frothybasin */
  776.    }
  777.    if((extra=find_extra_param(fractype)) > -1)
  778.       for(i=0;i<MAXPARAMS-4;i++) 
  779.          param[i+4] = moreparams[extra].paramvalue[i];
  780.    if(debugflag != 3200)
  781.       bf_math = 0;
  782.    else if(bf_math)
  783.       fractal_floattobf();
  784. }
  785.  
  786. #define MAXFRACTALS 25 
  787.  
  788. int build_fractal_list(int fractals[], int *last_val, char *nameptr[])
  789. {
  790.     int numfractals,i;
  791.  
  792.     numfractals = 0;
  793.     for (i = 0; i < num_fractal_types; i++)
  794.     {
  795.     if ((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*')
  796.     {
  797.         fractals[numfractals] = i;
  798.         if (i == neworbittype || i == fractalspecific[neworbittype].tofloat)
  799.         *last_val = numfractals;
  800.         nameptr[numfractals] = fractalspecific[i].name;
  801.         numfractals++;
  802.         if (numfractals >= MAXFRACTALS)
  803.         break;
  804.     }
  805.     }
  806.     return (numfractals);
  807. }
  808.  
  809. static FCODE v0a[] = {"From cx (real part)"};
  810. static FCODE v1a[] = {"From cy (imaginary part)"};
  811. static FCODE v2a[] = {"To   cx (real part)"};
  812. static FCODE v3a[] = {"To   cy (imaginary part)"};
  813.  
  814. /* 4D Mandelbrot */
  815. static FCODE v0b[] = {"From cj (3rd dim)"};
  816. static FCODE v1b[] = {"From ck (4th dim)"};
  817. static FCODE v2b[] = {"To   cj (3rd dim)"};
  818. static FCODE v3b[] = {"To   ck (4th dim)"};
  819.  
  820. /* 4D Julia */
  821. static FCODE v0c[] = {"From zj (3rd dim)"};
  822. static FCODE v1c[] = {"From zk (4th dim)"};
  823. static FCODE v2c[] = {"To   zj (3rd dim)"};
  824. static FCODE v3c[] = {"To   zk (4th dim)"};
  825.  
  826. static FCODE v4[] = {"Number of z pixels"};
  827. static FCODE v5[] = {"Location of z origin"};
  828. static FCODE v6[] = {"Depth of z"};
  829. static FCODE v7[] = {"Screen height"};
  830. static FCODE v8[] = {"Screen width"};
  831. static FCODE v9[] = {"Distance to Screen"};
  832. static FCODE v10[] = {"Distance between eyes"};
  833. static FCODE v11[] = {"3D Mode"};
  834. char *juli3Doptions[] = {"monocular","lefteye","righteye","red-blue"};
  835.  
  836. /* JIIM */
  837. #ifdef RANDOM_RUN
  838. static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk, Random Run?";
  839. char *JIIMmethod[] = {"breadth", "depth", "walk", "run"};
  840. #else
  841. static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk";
  842. char *JIIMmethod[] = {"breadth", "depth", "walk"};
  843. #endif
  844. static FCODE JIIMstr2[] = "Left first or Right first?";
  845. char *JIIMleftright[] = {"left", "right"};
  846.  
  847. /* --------------------------------------------------------------------- */
  848. int get_fract_params(int caller)    /* prompt for type-specific parms */
  849. {
  850.    char far *v0 = v0a;
  851.    char far *v1 = v1a;
  852.    char far *v2 = v2a;
  853.    char far *v3 = v3a;
  854.    char *juliorbitname = NULL;
  855.    int i,j,k;
  856.    int curtype,numparams,numtrig;
  857.    struct fullscreenvalues paramvalues[30];
  858.    char far *choices[30];
  859.    long oldbailout = 0L;
  860.    int promptnum;
  861.    char msg[120];
  862.    char *typename, *tmpptr;
  863.    char bailoutmsg[50];
  864.    int ret = 0;
  865.    int oldhelpmode;
  866.    static FCODE t1[] = {"First Function"};
  867.    static FCODE t2[] = {"Second Function"};
  868.    static FCODE t3[] = {"Third Function"};
  869.    static FCODE t4[] = {"Fourth Function"};
  870.    static FCODE *trg[] = {t1, t2, t3, t4};
  871.    char *filename,*entryname;
  872.    FILE *entryfile;
  873.    char *trignameptr[25];
  874. #ifdef XFRACT
  875.    static /* Can't initialize aggregates on the stack */
  876. #endif
  877.    char *bailnameptr[] = {s_mod,s_real,s_imag,s_or,s_and};
  878.    struct fractalspecificstuff far *jborbit = NULL;
  879.    struct fractalspecificstuff far *savespecific;
  880.    int firstparm =0;
  881.    int lastparm  = MAXPARAMS;
  882.    double oldparam[MAXPARAMS];
  883.    int fkeymask = 0x40;
  884.    oldbailout = bailout;
  885.    if(fractype==JULIBROT || fractype==JULIBROTFP)
  886.       julibrot = 1;
  887.    else
  888.       julibrot = 0;
  889.    curtype = fractype;
  890.    if (curfractalspecific->name[0] == '*'
  891.      && (i = curfractalspecific->tofloat) != NOFRACTAL  /* FIXED BUG HERE!! */
  892.      && fractalspecific[i].name[0] != '*')
  893.       curtype = i;
  894.    curfractalspecific = &fractalspecific[curtype];
  895.    tstack[0] = 0;
  896.    if ((i = curfractalspecific->helpformula) < -1) {
  897.       if (i == -2) { /* special for formula */
  898.      filename = FormFileName;
  899.      entryname = FormName;
  900.      }
  901.       else if (i == -3)  {     /* special for lsystem */
  902.      filename = LFileName;
  903.      entryname = LName;
  904.      }
  905.       else if (i == -4)  {     /* special for ifs */
  906.      filename = IFSFileName;
  907.      entryname = IFSName;
  908.      }
  909.       else { /* this shouldn't happen */
  910.          filename = NULL;
  911.          entryname = NULL;
  912.       }        
  913.       if (find_file_item(filename,entryname,&entryfile) == 0) {
  914.      load_entry_text(entryfile,tstack,16);
  915.      fclose(entryfile);
  916.      if(fractype == FORMULA || fractype == FFORMULA)
  917.        RunForm(entryname); /* no error check, should be okay, from above */
  918.      }
  919.       }
  920.    else if (i >= 0) {
  921.       int c,lines;
  922.       read_help_topic(i,0,2000,tstack); /* need error handling here ?? */
  923.       tstack[2000-i] = 0;
  924.       i = j = lines = 0; k = 1;
  925.       while ((c = tstack[i++]) != 0) {
  926.      /* stop at ctl, blank, or line with col 1 nonblank, max 16 lines */
  927.      if (k && c == ' ' && ++k <= 5) { } /* skip 4 blanks at start of line */
  928.      else {
  929.         if (c == '\n') {
  930.            if (k) break; /* blank line */
  931.            if (++lines >= 16) break;
  932.            k = 1;
  933.            }
  934.         else if (c < 16) /* a special help format control char */
  935.            break;
  936.         else {
  937.            if (k == 1) /* line starts in column 1 */
  938.           break;
  939.            k = 0;
  940.            }
  941.         tstack[j++] = (char)c;
  942.         }
  943.      }
  944.       while (--j >= 0 && tstack[j] == '\n') { }
  945.       tstack[j+1] = 0;
  946.       }
  947. gfp_top:   
  948.    promptnum = 0;
  949.    if (julibrot)
  950.    {
  951.       i = select_fracttype(neworbittype);
  952.       if (i < 0) 
  953.       {
  954.          if (ret == 0)
  955.             ret = -1;
  956.          julibrot = 0;
  957.          goto gfp_exit;
  958.       }
  959.       else
  960.          neworbittype = i;
  961.       jborbit = &fractalspecific[neworbittype];
  962.       juliorbitname = jborbit->name;
  963.    }
  964.  
  965.    if(fractype == FORMULA || fractype == FFORMULA) {
  966.       if(uses_p1)  /* set first parameter */
  967.          firstparm = 0;
  968.       else if(uses_p2)
  969.          firstparm = 2;
  970.       else
  971.          firstparm = 4; /* uses_p3 or no parameter */
  972.  
  973.       if(uses_p3)  /* set last parameter */
  974.          lastparm = 6;
  975.       else if(uses_p2)
  976.          lastparm = 4;
  977.       else
  978.          lastparm = 2; /* uses_p1 or no parameter */
  979.    }
  980.  
  981.    promptnum = 0;
  982.  
  983.    savespecific = curfractalspecific;
  984.    if(julibrot)
  985.    {
  986.       curfractalspecific = jborbit;
  987.       firstparm = 2; /* in most case Julibrot does not need first two parms */
  988.       if(neworbittype == QUATJULFP     ||   /* all parameters needed */ 
  989.          neworbittype == HYPERCMPLXJFP)
  990.       {
  991.          firstparm = 0;
  992.          lastparm = 4;
  993.       }    
  994.       if(neworbittype == QUATFP        ||   /* no parameters needed */
  995.          neworbittype == HYPERCMPLXFP)
  996.          firstparm = 4; 
  997.    }   
  998.    numparams = 0;
  999.    
  1000.    for (i = firstparm; i < lastparm; i++) 
  1001.    {
  1002.       char tmpbuf[30];
  1003.       char *parm;
  1004.       if ((parm=typehasparm(julibrot?neworbittype:fractype,i))==NULL)
  1005.          break;
  1006.       numparams++;
  1007.       choices[promptnum] = parm;
  1008.       paramvalues[promptnum].type = 'd';
  1009.    
  1010.       if (choices[promptnum][0] == '+') 
  1011.       {
  1012.          choices[promptnum]++;
  1013.          paramvalues[promptnum].type = 'D';
  1014.       }
  1015.       else if (choices[promptnum][0] == '#') 
  1016.          choices[promptnum]++;
  1017.       sprintf(tmpbuf,"%.17g",param[i]);
  1018.       paramvalues[promptnum].uval.dval = atof(tmpbuf);
  1019.       oldparam[i] = paramvalues[promptnum++].uval.dval;
  1020.    }
  1021.  
  1022.    numtrig = (curfractalspecific->flags >> 6) & 7;
  1023.    if(curtype==FORMULA || curtype==FFORMULA ) {
  1024.       numtrig = maxfn;
  1025.       }
  1026.  
  1027.    if ((i = numtrigfn) > 27) i = 27;
  1028.    while (--i >= 0)
  1029.       trignameptr[i] = trigfn[i].name;
  1030.    for (i = 0; i < numtrig; i++) {
  1031.       paramvalues[promptnum].type = 'l';
  1032.       paramvalues[promptnum].uval.ch.val  = trigndx[i];
  1033.       paramvalues[promptnum].uval.ch.llen = numtrigfn;
  1034.       paramvalues[promptnum].uval.ch.vlen = 6;
  1035.       paramvalues[promptnum].uval.ch.list = trignameptr;
  1036.       choices[promptnum++] = (char far *)trg[i];
  1037.       }
  1038.    if (*(typename = curfractalspecific->name) == '*')
  1039.         ++typename;
  1040.  
  1041.    i = curfractalspecific->orbit_bailout;
  1042.  
  1043.    if( i != 0 && curfractalspecific->calctype == StandardFractal &&
  1044.        (curfractalspecific->flags & BAILTEST) &&
  1045.        potparam[0] == 0.0 && potparam[2] == 0.0 ) {
  1046.         static FCODE bailteststr[] = {"Bailout Test (mod, real, imag, or, and)"};
  1047.       paramvalues[promptnum].type = 'l';
  1048.       paramvalues[promptnum].uval.ch.val  = (int)bailoutest;
  1049.       paramvalues[promptnum].uval.ch.llen = 5;
  1050.       paramvalues[promptnum].uval.ch.vlen = 6;
  1051.       paramvalues[promptnum].uval.ch.list = bailnameptr;
  1052.       choices[promptnum++] = bailteststr;
  1053.    }
  1054.  
  1055.    if (i)
  1056.       if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  1057.       {
  1058.         static FCODE bailpotstr[] = {"Bailout: continuous potential (Y screen) value in use"};
  1059.      paramvalues[promptnum].type = '*';
  1060.      choices[promptnum++] = bailpotstr;
  1061.       }
  1062.       else 
  1063.       {
  1064.          static FCODE bailoutstr[] = {"Bailout value (0 means use default)"};
  1065.      choices[promptnum] = bailoutstr;
  1066.      paramvalues[promptnum].type = 'L';
  1067.      paramvalues[promptnum++].uval.Lval = (oldbailout = bailout);
  1068.      paramvalues[promptnum].type = '*';
  1069.      tmpptr = typename;
  1070.      if (usr_biomorph != -1) 
  1071.      {
  1072.         i = 100;
  1073.         tmpptr = "biomorph";
  1074.      }
  1075.      sprintf(bailoutmsg,"    (%s default is %d)",tmpptr,i);
  1076.      choices[promptnum++] = bailoutmsg;
  1077.       }
  1078.    if (julibrot)
  1079.    {
  1080.       switch(neworbittype)
  1081.       {
  1082.       case QUATFP:
  1083.       case HYPERCMPLXFP:
  1084.           v0 = v0b; v1 = v1b; v2 = v2b; v3 = v3b;
  1085.           break;
  1086.       case QUATJULFP:
  1087.       case HYPERCMPLXJFP:
  1088.           v0 = v0c; v1 = v1c; v2 = v2c; v3 = v3c;
  1089.           break;
  1090.       default:
  1091.           v0 = v0a; v1 = v1a; v2 = v2a; v3 = v3a;
  1092.          break;
  1093.       }
  1094.  
  1095.       curfractalspecific = savespecific;
  1096.       paramvalues[promptnum].uval.dval = mxmaxfp;
  1097.       paramvalues[promptnum].type = 'f';
  1098.       choices[promptnum++] = v0;
  1099.       paramvalues[promptnum].uval.dval = mymaxfp;
  1100.       paramvalues[promptnum].type = 'f';
  1101.       choices[promptnum++] = v1;
  1102.       paramvalues[promptnum].uval.dval = mxminfp;
  1103.       paramvalues[promptnum].type = 'f';
  1104.       choices[promptnum++] = v2;
  1105.       paramvalues[promptnum].uval.dval = myminfp;
  1106.       paramvalues[promptnum].type = 'f';
  1107.       choices[promptnum++] = v3;
  1108.       paramvalues[promptnum].uval.ival = zdots;
  1109.       paramvalues[promptnum].type = 'i';
  1110.       choices[promptnum++] = v4;
  1111.  
  1112.       paramvalues[promptnum].type = 'l';
  1113.       paramvalues[promptnum].uval.ch.val  = juli3Dmode;
  1114.       paramvalues[promptnum].uval.ch.llen = 4;
  1115.       paramvalues[promptnum].uval.ch.vlen = 9;
  1116.       paramvalues[promptnum].uval.ch.list = juli3Doptions;
  1117.       choices[promptnum++] = v11;
  1118.  
  1119.       paramvalues[promptnum].uval.dval = eyesfp;
  1120.       paramvalues[promptnum].type = 'f';
  1121.       choices[promptnum++] = v10;
  1122.       paramvalues[promptnum].uval.dval = originfp;
  1123.       paramvalues[promptnum].type = 'f';
  1124.       choices[promptnum++] = v5;
  1125.       paramvalues[promptnum].uval.dval = depthfp;
  1126.       paramvalues[promptnum].type = 'f';
  1127.       choices[promptnum++] = v6;
  1128.       paramvalues[promptnum].uval.dval = heightfp;
  1129.       paramvalues[promptnum].type = 'f';
  1130.       choices[promptnum++] = v7;
  1131.       paramvalues[promptnum].uval.dval = widthfp;
  1132.       paramvalues[promptnum].type = 'f';
  1133.       choices[promptnum++] = v8;
  1134.       paramvalues[promptnum].uval.dval = distfp;
  1135.       paramvalues[promptnum].type = 'f';
  1136.       choices[promptnum++] = v9;
  1137.    }
  1138.  
  1139.    if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  1140.    {
  1141.       choices[promptnum] = JIIMstr1;
  1142.       paramvalues[promptnum].type = 'l';
  1143.       paramvalues[promptnum].uval.ch.list = JIIMmethod;
  1144.       paramvalues[promptnum].uval.ch.vlen = 7;
  1145. #ifdef RANDOM_RUN
  1146.       paramvalues[promptnum].uval.ch.llen = 4;
  1147. #else
  1148.       paramvalues[promptnum].uval.ch.llen = 3; /* disable random run */
  1149. #endif
  1150.       paramvalues[promptnum++].uval.ch.val  = major_method;
  1151.  
  1152.       choices[promptnum] = JIIMstr2;
  1153.       paramvalues[promptnum].type = 'l';
  1154.       paramvalues[promptnum].uval.ch.list = JIIMleftright;
  1155.       paramvalues[promptnum].uval.ch.vlen = 5;
  1156.       paramvalues[promptnum].uval.ch.llen = 2;
  1157.       paramvalues[promptnum++].uval.ch.val  = minor_method;
  1158.    }
  1159.  
  1160.    if (caller                /* <z> command ? */
  1161. /*      && (display3d > 0 || promptnum == 0)) */
  1162.       && (display3d > 0))
  1163.       {
  1164.        static FCODE msg[]={"Current type has no type-specific parameters"};
  1165.        stopmsg(20,msg);
  1166.        goto gfp_exit;
  1167.        }
  1168.    if(julibrot)
  1169.       sprintf(msg,"Julibrot Parameters (orbit= %s)",juliorbitname);
  1170.    else
  1171.       sprintf(msg,"Parameters for fractal type %s",typename);
  1172.    if(bf_math == 0)
  1173.    {
  1174.       static FCODE msg1[] = {"\n(Press F6 for corner parameters)"};
  1175.       far_strcat(msg,msg1);
  1176.    }
  1177.    else
  1178.       fkeymask = 0;
  1179.    for(;;)
  1180.    {
  1181.       oldhelpmode = helpmode;
  1182.       helpmode = curfractalspecific->helptext;
  1183.       i = fullscreen_prompt(msg,promptnum,choices,paramvalues,fkeymask,tstack);
  1184.       helpmode = oldhelpmode;
  1185.       if (i < 0) 
  1186.       {
  1187.          if(julibrot)
  1188.            goto gfp_top;
  1189.      if (ret == 0)
  1190.         ret = -1;
  1191.      goto gfp_exit;
  1192.       }
  1193.       if (i != F6) 
  1194.          break;
  1195.       if(bf_math == 0)
  1196.          if (get_corners() > 0)
  1197.         ret = 1;
  1198.      }
  1199.      promptnum = 0;
  1200.      for ( i = firstparm; i < numparams+firstparm; i++) 
  1201.      {
  1202.         if (oldparam[i] != paramvalues[promptnum].uval.dval) 
  1203.         {
  1204.            param[i] = paramvalues[promptnum].uval.dval;
  1205.           ret = 1;
  1206.         }
  1207.         ++promptnum;
  1208.     }
  1209.  
  1210.    for ( i = 0; i < numtrig; i++) 
  1211.    {
  1212.       if (paramvalues[promptnum].uval.ch.val != (int)trigndx[i]) 
  1213.       {
  1214.      set_trig_array(i,trigfn[paramvalues[promptnum].uval.ch.val].name);
  1215.      ret = 1;
  1216.       }
  1217.       ++promptnum;
  1218.    }
  1219.  
  1220.    if(julibrot)
  1221.    {
  1222.       savespecific = curfractalspecific;
  1223.       curfractalspecific = jborbit;
  1224.    }   
  1225.  
  1226.    i = curfractalspecific->orbit_bailout;
  1227.  
  1228.    if( i != 0 && curfractalspecific->calctype == StandardFractal &&
  1229.        (curfractalspecific->flags & BAILTEST) &&
  1230.        potparam[0] == 0.0 && potparam[2] == 0.0 ) {
  1231.       if (paramvalues[promptnum].uval.ch.val != (int)bailoutest) {
  1232.         bailoutest = (enum bailouts)paramvalues[promptnum].uval.ch.val;
  1233.         ret = 1;
  1234.       }
  1235.       promptnum++;
  1236.    }
  1237.    else
  1238.       bailoutest = Mod;
  1239.    setbailoutformula(bailoutest);
  1240.  
  1241.    if (i)
  1242.       if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  1243.      promptnum++;
  1244.       else 
  1245.       {
  1246.          bailout = paramvalues[promptnum++].uval.Lval;
  1247.          if (bailout != 0 && (bailout < 1 || bailout > 2100000000L))
  1248.         bailout = oldbailout;
  1249.          if (bailout != oldbailout)
  1250.         ret = 1;
  1251.      promptnum++;
  1252.       }
  1253.  
  1254.      if (julibrot)
  1255.      {
  1256.     mxmaxfp    = paramvalues[promptnum++].uval.dval;
  1257.     mymaxfp    = paramvalues[promptnum++].uval.dval;
  1258.     mxminfp    = paramvalues[promptnum++].uval.dval;
  1259.     myminfp    = paramvalues[promptnum++].uval.dval;
  1260.     zdots      = paramvalues[promptnum++].uval.ival;
  1261.         juli3Dmode = paramvalues[promptnum++].uval.ch.val;
  1262.     eyesfp     = (float)paramvalues[promptnum++].uval.dval;
  1263.     originfp   = (float)paramvalues[promptnum++].uval.dval;
  1264.     depthfp    = (float)paramvalues[promptnum++].uval.dval;
  1265.     heightfp   = (float)paramvalues[promptnum++].uval.dval;
  1266.     widthfp    = (float)paramvalues[promptnum++].uval.dval;
  1267.     distfp     = (float)paramvalues[promptnum++].uval.dval;
  1268.         ret = 1;  /* force new calc since not resumable anyway */
  1269.      }
  1270.       if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  1271.       {
  1272.      if (paramvalues[promptnum].uval.ch.val != major_method ||
  1273.          paramvalues[promptnum+1].uval.ch.val != minor_method)
  1274.         ret = 1;
  1275.      major_method = (enum Major)paramvalues[promptnum  ].uval.ch.val;
  1276.      minor_method = (enum Minor)paramvalues[promptnum+1].uval.ch.val;
  1277.       }
  1278.  
  1279. gfp_exit:
  1280.    curfractalspecific = &fractalspecific[fractype];
  1281.    return(ret);
  1282. }
  1283.  
  1284. int find_extra_param(int type)
  1285. {
  1286.    int i,ret,curtyp;
  1287.    ret = -1;
  1288.    i= -1;
  1289.  
  1290.    if(fractalspecific[type].flags&MORE)
  1291.    {
  1292.       while((curtyp=moreparams[++i].type) != type && curtyp != -1);
  1293.       if(curtyp == type)
  1294.         ret = i;
  1295.    }  
  1296.    return(ret);
  1297. }     
  1298.  
  1299. int check_orbit_name(char *orbitname)
  1300. {
  1301.    int i, numtypes, bad;
  1302.    char *nameptr[MAXFRACTALS];
  1303.    int fractals[MAXFRACTALS];
  1304.    int last_val;
  1305.  
  1306.    numtypes = build_fractal_list(fractals, &last_val, nameptr);
  1307.    bad = 1;
  1308.    for(i=0;i<numtypes;i++)
  1309.    {
  1310.       if(strcmp(orbitname,nameptr[i]) == 0)
  1311.       {
  1312.          neworbittype = fractals[i];
  1313.          bad = 0;
  1314.          break;
  1315.       }
  1316.    }
  1317.    return(bad);
  1318. }
  1319.  
  1320. /* --------------------------------------------------------------------- */
  1321.  
  1322. static FILE *gfe_file;
  1323.  
  1324. long get_file_entry(int type,char *title,char *fmask,
  1325.               char *filename,char *entryname)
  1326. {
  1327.    /* Formula, LSystem, etc type structure, select from file */
  1328.    /* containing definitions in the form    name { ... }     */
  1329.    int newfile,firsttry;
  1330.    long entry_pointer;
  1331.    newfile = 0;
  1332.    for(;;) {
  1333.       firsttry = 0;
  1334.       /* pb: binary mode used here - it is more work, but much faster, */
  1335.       /*     especially when ftell or fgetpos is used               */
  1336.       while (newfile || (gfe_file = fopen(filename, "rb")) == NULL) {
  1337.      char buf[60];
  1338.      newfile = 0;
  1339.      if (firsttry) {
  1340.         sprintf(temp1,s_cantfind, filename);
  1341.         stopmsg(0,temp1);
  1342.         }
  1343.      sprintf(buf,"Select %s File",title);
  1344.      if (getafilename(buf,fmask,filename) < 0)
  1345.         return -1;
  1346.         
  1347.      firsttry = 1; /* if around open loop again it is an error */
  1348.      }
  1349.       setvbuf(gfe_file,tstack,_IOFBF,4096); /* improves speed when file is big */
  1350.       newfile = 0;
  1351.       if ((entry_pointer = gfe_choose_entry(type,title,filename,entryname)) == -2) {
  1352.      newfile = 1; /* go to file list, */
  1353.      continue;    /* back to getafilename */
  1354.      }
  1355.       if (entry_pointer == -1)
  1356.      return -1;
  1357.       switch (type) {
  1358.      case GETFORMULA:
  1359.         if (RunForm(entryname) == 0) return 0;
  1360.         break;
  1361.      case GETLSYS:
  1362.         if (LLoad() == 0) return 0;
  1363.         break;
  1364.      case GETIFS:
  1365.         if (ifsload() == 0) {
  1366.            fractype = (ifs_type == 0) ? IFS : IFS3D;
  1367.            curfractalspecific = &fractalspecific[fractype];
  1368.            set_default_parms(); /* to correct them if 3d */
  1369.            return 0;
  1370.            }
  1371.         break;
  1372.      case GETPARM:
  1373.         return entry_pointer;
  1374.      }
  1375.       }
  1376. }
  1377.  
  1378. struct entryinfo {
  1379.    char name[ITEMNAMELEN+2];
  1380.    long point; /* points to the ( or the { following the name */
  1381.    };
  1382. static struct entryinfo far *far*gfe_choices; /* for format_getparm_line */
  1383. static char *gfe_title;
  1384.  
  1385. /* skip to next non-white space character and return it */
  1386. int skip_white_space(FILE *infile, long *file_offset)
  1387. {
  1388.    int c;
  1389.    do
  1390.    {
  1391.       c = getc(infile);
  1392.       (*file_offset)++; 
  1393.    }
  1394.    while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
  1395.    return(c);
  1396. }
  1397.  
  1398. /* skip to end of line */
  1399. int skip_comment(FILE *infile, long *file_offset)
  1400. {
  1401.    int c;
  1402.    do
  1403.    {
  1404.       c = getc(infile);
  1405.       (*file_offset)++; 
  1406.    }
  1407.    while (c != '\n' && c != '\r' && c != EOF && c != '\032');
  1408.    return(c); 
  1409. }
  1410.  
  1411. #define MAXENTRIES 2000L
  1412. int scan_entries(FILE * infile, void far * ch, char *itemname)
  1413. {
  1414.    struct entryinfo far *far * choices;
  1415.    char buf[101];
  1416.    long name_offset, file_offset = -1;
  1417.    int numentries = 0;
  1418.  
  1419.    choices = (struct entryinfo far * far *) ch;
  1420.  
  1421.    for (;;)
  1422.    {                            /* scan the file for entry names */
  1423.       int c, len;
  1424.       if ((c = skip_white_space(infile, &file_offset)) == ';')
  1425.       {
  1426.          c = skip_comment(infile, &file_offset);
  1427.          if (c == EOF || c == '\032')
  1428.             break;
  1429.          continue;
  1430.       }
  1431.       name_offset = file_offset;
  1432.       /* next equiv roughly to fscanf(..,"%40[^* \n\r\t({\032]",buf) */
  1433.       len = 0; 
  1434.       while (c != ' ' && c != '\t' && c != '(' && c != ';'
  1435.            && c != '{' && c != '\n' && c != '\r' && c != EOF && c != '\032')
  1436.       {
  1437.          if (len < 40)
  1438.             buf[len++] = (char) c;
  1439.          c = getc(infile);
  1440.          ++file_offset;
  1441.       }
  1442.       buf[len] = 0;
  1443.       while (c != '{' && /* c != '\n' && c != '\r' && */  c != EOF && c != '\032')
  1444.       {
  1445.          if(c == ';')
  1446.             c = skip_comment(infile, &file_offset);
  1447.          else
  1448.          { 
  1449.             c = getc(infile);
  1450.             ++file_offset;
  1451.          }   
  1452.       }
  1453.       if (c == '{')
  1454.       {
  1455.          while (c != '}' && c != EOF && c != '\032')
  1456.          {
  1457.             if(c == ';')
  1458.                c = skip_comment(infile, &file_offset);
  1459.             else
  1460.             {
  1461.                c = getc(infile);
  1462.                ++file_offset;
  1463.             }   
  1464.          }
  1465.          if (c != '}')
  1466.             break;
  1467.          buf[ITEMNAMELEN] = 0;
  1468.          if (itemname != NULL)  /* looking for one entry */
  1469.          {
  1470.             if (stricmp(buf, itemname) == 0)
  1471.             {
  1472.                fseek(infile, name_offset, SEEK_SET);
  1473.                return (-1);
  1474.             }
  1475.          }
  1476.          else /* make a whole list of entries */
  1477.          {
  1478.             if (buf[0] != 0 && stricmp(buf, "comment") != 0)
  1479.             {
  1480.                far_strcpy(choices[numentries]->name, buf);
  1481.                choices[numentries]->point = name_offset;
  1482.                if (++numentries >= MAXENTRIES)
  1483.                {
  1484.                   sprintf(buf, "Too many entries in file, first %ld used", MAXENTRIES);
  1485.                   stopmsg(0, buf);
  1486.                   break;
  1487.                }
  1488.             }
  1489.          }
  1490.       }
  1491.       else if (c == EOF || c == '\032')
  1492.          break;
  1493.    }
  1494.    return (numentries);
  1495. }
  1496.  
  1497. static long gfe_choose_entry(int type,char *title,char *filename,char *entryname)
  1498. /* subrtn of get_file_entry, separated so that storage gets freed up */
  1499. {
  1500.    static FCODE o_instr[]={"Press F6 to select different file, F2 for details, F4 to toggle sort "};
  1501.    int numentries, i;
  1502.    char buf[101];
  1503.    struct entryinfo far * far *choices;
  1504.    int far *attributes;
  1505.    void (*formatitem)(int, char *);
  1506.    int boxwidth,boxdepth,colwidth;
  1507.    static int dosort = 1;
  1508.    int options = 8;
  1509.    char far *instr;   
  1510.    /* steal existing array for "choices" */
  1511.    choices = (struct entryinfo far *far*)MK_FP(extraseg,0);
  1512.    /* leave room for details F2 */  
  1513.    choices = choices + (2048/sizeof(struct entryinfo far *far*)); 
  1514.    choices[0] = (struct entryinfo far *)(choices + MAXENTRIES+1);
  1515.    attributes = (int far *)(choices[0] + MAXENTRIES+1);
  1516.    instr = (char far *)(attributes + MAXENTRIES +1);
  1517.    gfe_choices = &choices[0];
  1518.    gfe_title = title;
  1519. retry:
  1520.    attributes[0] = 1;
  1521.    for(i=1;i<MAXENTRIES+1;i++)
  1522.    {
  1523.       choices[i] = choices[i-1] + 1;
  1524.       attributes[i] = 1;
  1525.    }
  1526.  
  1527.    numentries = 0;
  1528.    helptitle(); /* to display a clue when file big and next is slow */
  1529.  
  1530.    numentries=scan_entries(gfe_file,choices,NULL);
  1531.    if (numentries == 0) {
  1532.       static FCODE msg[]={"File doesn't contain any valid entries"};
  1533.       stopmsg(0,msg);
  1534.       fclose(gfe_file);
  1535.       return -2; /* back to file list */
  1536.       }
  1537.    far_strcpy(instr,o_instr);
  1538.    if(dosort)
  1539.    {
  1540.       far_strcat(instr,"off");
  1541.       shell_sort((char far *)choices,numentries,sizeof(char far *),lccompare);
  1542.    }
  1543.    else
  1544.       far_strcat(instr,"on");
  1545.    
  1546.    strcpy(buf,entryname); /* preset to last choice made */
  1547.    sprintf(temp1,"%s Selection\nFile: %s",title,filename);
  1548.    formatitem = NULL;
  1549.    boxwidth = colwidth = boxdepth = 0;
  1550.    if (type == GETPARM) {
  1551.       formatitem = format_parmfile_line;
  1552.       boxwidth = 1;
  1553.       boxdepth = 16;
  1554.       colwidth = 76;
  1555.       }
  1556.    if(dosort)
  1557.       options = 8;
  1558.    else
  1559.       options = 8+32;   
  1560.    i = fullscreen_choice(options,temp1,NULL,instr,numentries,(char far*far*)choices,
  1561.                            attributes,boxwidth,boxdepth,colwidth,0,
  1562.                formatitem,buf,NULL,check_gfe_key);
  1563.    if (i == 0-F4)
  1564.    {
  1565.      rewind(gfe_file);
  1566.      dosort = 1-dosort;
  1567.      goto retry;
  1568.    }
  1569.    fclose(gfe_file);
  1570.    if (i < 0) {
  1571.       if (i == 0-F6)
  1572.      return -2; /* go back to file list */
  1573.       return -1;    /* cancel */
  1574.       }
  1575.    far_strcpy(entryname, choices[i]->name);
  1576.    return(choices[i]->point);
  1577. }
  1578.  
  1579.  
  1580. static int check_gfe_key(int curkey,int choice)
  1581. {
  1582.    char infhdg[60];
  1583.    char far *infbuf;
  1584.  
  1585.    if (curkey == F6)
  1586.       return 0-F6;
  1587.    if (curkey == F4)
  1588.       return 0-F4;
  1589.    if (curkey == F2) {
  1590.       infbuf = MK_FP(extraseg,0);
  1591.       fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  1592.       load_entry_text(gfe_file,infbuf,16);
  1593.       strcpy(infhdg,gfe_title);
  1594.       strcat(infhdg," file entry:\n\n");
  1595.  /* ... instead, call help with buffer?  heading added */
  1596.       stackscreen();
  1597.       helptitle();
  1598.       setattr(1,0,C_GENERAL_MED,24*80);
  1599.       putstring(2,1,C_GENERAL_HI,infhdg);
  1600.       textcbase = 2; /* left margin is 2 */
  1601.       putstring(-1,0,C_GENERAL_MED,infbuf);
  1602.       {
  1603.       static FCODE msg[] = {"\n\n\nPress any key to return to selection list"};
  1604.       putstring(-1,0,C_GENERAL_LO,msg);
  1605.       }
  1606.       textcbase = 0;
  1607.       movecursor(25,80);
  1608.       getakeynohelp();
  1609.       unstackscreen();
  1610.       }
  1611.    return 0;
  1612. }
  1613.  
  1614. static void load_entry_text(FILE *entfile,char far *buf,int maxlines)
  1615. {
  1616.    int linect,linelen,c,comment=0;
  1617.    linect = linelen = 0;
  1618.    while ((c = fgetc(entfile)) != EOF && c != '\032') {
  1619.       if (c == ';')
  1620.          comment = 1;
  1621.       else if (c == '\n' || c == '\r')
  1622.          comment = 0;         
  1623.       if (c != '\r') {
  1624.      if (c == '\t') {
  1625.         while ((linelen % 8) != 7 && linelen < 75) { /* 76 wide max */
  1626.            *(buf++) = ' ';
  1627.            ++linelen;
  1628.            }
  1629.         c = ' ';
  1630.         }
  1631.      if (c == '\n') {
  1632.         if (++linect > maxlines) break;
  1633.         linelen = -1;
  1634.         }
  1635.      if (++linelen > 75) {
  1636.         if (linelen == 76) *(buf++) = '\021';
  1637.         }
  1638.      else
  1639.         *(buf++) = (char)c;
  1640.      if (comment == 0 && c == '}') break;
  1641.      }
  1642.       }
  1643.    *buf = 0;
  1644. }
  1645.  
  1646. static void format_parmfile_line(int choice,char *buf)
  1647. {
  1648.    int c,i;
  1649.    char line[80];
  1650.    fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  1651.    while (getc(gfe_file) != '{') { }
  1652.    while ((c = getc(gfe_file)) == ' ' || c == '\t' || c == ';') { }
  1653.    i = 0;
  1654.    while (i < 56 && c != '\n' && c != '\r' && c != EOF && c != '\032') {
  1655.       line[i++] = (char)((c == '\t') ? ' ' : c);
  1656.       c = getc(gfe_file);
  1657.       }
  1658.    line[i] = 0;
  1659. #ifndef XFRACT   
  1660.    sprintf(buf,"%-20Fs%-56s",gfe_choices[choice]->name,line);
  1661. #else
  1662.    sprintf(buf,"%-20s%-56s",gfe_choices[choice]->name,line);
  1663. #endif
  1664. }
  1665.  
  1666. /* --------------------------------------------------------------------- */
  1667.  
  1668. int get_fract3d_params() /* prompt for 3D fractal parameters */
  1669. {
  1670.    int i,k,ret,oldhelpmode;
  1671.    static FCODE hdg[] = {"3D Parameters"};
  1672.    static FCODE p1[] = {"X-axis rotation in degrees"};
  1673.    static FCODE p2[] = {"Y-axis rotation in degrees"};
  1674.    static FCODE p3[] = {"Z-axis rotation in degrees"};
  1675.    static FCODE p4[] = {"Perspective distance [1 - 999, 0 for no persp]"};
  1676.    static FCODE p5[] = {"X shift with perspective (positive = right)"};
  1677.    static FCODE p6[] = {"Y shift with perspective (positive = up   )"};
  1678.    static FCODE p7[] = {"Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)"};
  1679.    struct fullscreenvalues uvalues[20];
  1680.    char far *ifs3d_prompts[8];
  1681.  
  1682.    stackscreen();
  1683.    ifs3d_prompts[0] = p1;
  1684.    ifs3d_prompts[1] = p2;
  1685.    ifs3d_prompts[2] = p3;
  1686.    ifs3d_prompts[3] = p4;
  1687.    ifs3d_prompts[4] = p5;
  1688.    ifs3d_prompts[5] = p6;
  1689.    ifs3d_prompts[6] = p7;
  1690.    k = 0;
  1691.    uvalues[k].type = 'i';
  1692.    uvalues[k++].uval.ival = XROT;
  1693.    uvalues[k].type = 'i';
  1694.    uvalues[k++].uval.ival = YROT;
  1695.    uvalues[k].type = 'i';
  1696.    uvalues[k++].uval.ival = ZROT;
  1697.    uvalues[k].type = 'i';
  1698.    uvalues[k++].uval.ival = ZVIEWER;
  1699.    uvalues[k].type = 'i';
  1700.    uvalues[k++].uval.ival = XSHIFT;
  1701.    uvalues[k].type = 'i';
  1702.    uvalues[k++].uval.ival = YSHIFT;
  1703.    uvalues[k].type = 'i';
  1704.    uvalues[k++].uval.ival = glassestype;
  1705.  
  1706.    oldhelpmode = helpmode;
  1707.    helpmode = HELP3DFRACT;
  1708.    i = fullscreen_prompt(hdg,k,ifs3d_prompts,uvalues,0,NULL);
  1709.    helpmode = oldhelpmode;
  1710.    if (i < 0) {
  1711.       ret = -1;
  1712.       goto get_f3d_exit;
  1713.       }
  1714.  
  1715.    ret = k = 0;
  1716.    XROT    =  uvalues[k++].uval.ival;
  1717.    YROT    =  uvalues[k++].uval.ival;
  1718.    ZROT    =  uvalues[k++].uval.ival;
  1719.    ZVIEWER =  uvalues[k++].uval.ival;
  1720.    XSHIFT  =  uvalues[k++].uval.ival;
  1721.    YSHIFT  =  uvalues[k++].uval.ival;
  1722.    glassestype = uvalues[k++].uval.ival;
  1723.    if (glassestype < 0 || glassestype > 3) glassestype = 0;
  1724.    if (glassestype)
  1725.       if (get_funny_glasses_params() || check_mapfile())
  1726.      ret = -1;
  1727.  
  1728. get_f3d_exit:
  1729.    unstackscreen();
  1730.    return(ret);
  1731. }
  1732.  
  1733. /* --------------------------------------------------------------------- */
  1734. /* These macros streamline the "save near space" campaign */ 
  1735.  
  1736. #define LOADPROMPTS3D(X)     {\
  1737.    static FCODE tmp[] = { X };\
  1738.    prompts3d[++k]= tmp;\
  1739.    }
  1740.  
  1741. #define LOADPROMPTSCHOICES(X)     {\
  1742.    static FCODE tmp[] = { X };\
  1743.    choices[k++]= tmp;\
  1744.    }
  1745.    
  1746. int get_3d_params()    /* prompt for 3D parameters */
  1747. {
  1748.    static FCODE hdg[]={"3D Mode Selection"};
  1749.    static FCODE hdg1[]={"Select 3D Fill Type"};
  1750.    char far *choices[11];
  1751.    int attributes[21];
  1752.    int sphere;
  1753.    char far *s;
  1754.    static FCODE s1[] = {"              Sphere 3D Parameters\n\
  1755. Sphere is on its side; North pole to right\n\
  1756. Long. 180 is top, 0 is bottom; Lat. -90 is left, 90 is right"};
  1757.    static char s2[]={"              Planar 3D Parameters\n\
  1758. Pre-rotation X axis is screen top; Y axis is left side\n\
  1759. Pre-rotation Z axis is coming at you out of the screen!"};
  1760.    char far *prompts3d[21];
  1761.    struct fullscreenvalues uvalues[21];
  1762.    int i, k;
  1763.    int oldhelpmode;
  1764.  
  1765. #ifdef WINFRACT
  1766.      {
  1767.      extern int far wintext_textmode;
  1768.      if (wintext_textmode != 2)  /* are we in textmode? */
  1769.          return(0);              /* no - prompts are already handled */
  1770.      }
  1771. #endif
  1772. restart_1:
  1773.     if (Targa_Out && overlay3d)
  1774.         Targa_Overlay = 1;
  1775.  
  1776.    k= -1;
  1777.  
  1778.    LOADPROMPTS3D("Preview Mode?");
  1779.    uvalues[k].type = 'y';
  1780.    uvalues[k].uval.ch.val = preview;
  1781.  
  1782.    LOADPROMPTS3D("    Show Box?");
  1783.    uvalues[k].type = 'y';
  1784.    uvalues[k].uval.ch.val = showbox;
  1785.    
  1786.    LOADPROMPTS3D("Coarseness, preview/grid/ray (in y dir)");
  1787.    uvalues[k].type = 'i';
  1788.    uvalues[k].uval.ival = previewfactor;
  1789.  
  1790.    LOADPROMPTS3D("Spherical Projection?");
  1791.    uvalues[k].type = 'y';
  1792.    uvalues[k].uval.ch.val = sphere = SPHERE;
  1793.  
  1794.    LOADPROMPTS3D("Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)");
  1795.    uvalues[k].type = 'i';
  1796.    uvalues[k].uval.ival = glassestype;
  1797.  
  1798.    LOADPROMPTS3D("Ray trace out? (0=No, 1=DKB/POVRay, 2=VIVID, 3=RAW,");
  1799.    uvalues[k].type = 'i';
  1800.    uvalues[k].uval.ival = RAY;
  1801.  
  1802.    LOADPROMPTS3D("                4=MTV, 5=RAYSHADE, 6=ACROSPIN, 7=DXF)");
  1803.    uvalues[k].type = '*';
  1804.  
  1805.    LOADPROMPTS3D("    Brief output?");
  1806.    uvalues[k].type = 'y';
  1807.    uvalues[k].uval.ch.val = BRIEF;
  1808.  
  1809.    check_writefile(ray_name,".ray");
  1810.    LOADPROMPTS3D("    Output File Name");
  1811.    uvalues[k].type = 's';
  1812.    strcpy(uvalues[k].uval.sval,ray_name);
  1813.  
  1814.    LOADPROMPTS3D("Targa output?");
  1815.    uvalues[k].type = 'y';
  1816.    uvalues[k].uval.ch.val = Targa_Out;
  1817.  
  1818.    LOADPROMPTS3D("Use grayscale value for depth? (if \"no\" uses color number)");
  1819.    uvalues[k].type = 'y';
  1820.    uvalues[k].uval.ch.val = grayflag;
  1821.  
  1822.    oldhelpmode = helpmode;
  1823.    helpmode = HELP3DMODE;
  1824.  
  1825.    k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
  1826.    helpmode = oldhelpmode;
  1827.    if (k < 0) {
  1828.       return(-1);
  1829.       }
  1830.  
  1831.    k=0;
  1832.  
  1833.    preview = (char)uvalues[k++].uval.ch.val;
  1834.  
  1835.    showbox = (char)uvalues[k++].uval.ch.val;
  1836.  
  1837.    previewfactor  = uvalues[k++].uval.ival;
  1838.  
  1839.    sphere = uvalues[k++].uval.ch.val;
  1840.  
  1841.    glassestype = uvalues[k++].uval.ival;
  1842.  
  1843.    RAY = uvalues[k++].uval.ival;
  1844.    k++;
  1845.    {
  1846.       static FCODE msg[] = {
  1847. "DKB/POV-Ray output is obsolete but still works. See \"Ray Tracing Output\" in\n\
  1848. the online documentation."};
  1849.       if(RAY == 1)
  1850.          stopmsg(0,msg);
  1851.    }
  1852.    BRIEF = uvalues[k++].uval.ch.val;
  1853.  
  1854.    strcpy(ray_name,uvalues[k++].uval.sval);
  1855.  
  1856.    Targa_Out = uvalues[k++].uval.ch.val;
  1857.    grayflag  = (char)uvalues[k++].uval.ch.val;
  1858.  
  1859.    /* check ranges */
  1860.    if(previewfactor < 2)
  1861.       previewfactor = 2;
  1862.    if(previewfactor > 2000)
  1863.       previewfactor = 2000;
  1864.  
  1865.    if(sphere && !SPHERE)
  1866.    {
  1867.       SPHERE = TRUE;
  1868.       set_3d_defaults();
  1869.    }
  1870.    else if(!sphere && SPHERE)
  1871.    {
  1872.       SPHERE = FALSE;
  1873.       set_3d_defaults();
  1874.    }
  1875.  
  1876.    if(glassestype < 0)
  1877.       glassestype = 0;
  1878.    if(glassestype > 3)
  1879.       glassestype = 3;
  1880.    if(glassestype)
  1881.       whichimage = 1;
  1882.  
  1883.    if (RAY < 0)
  1884.       RAY = 0;
  1885.    if (RAY > 7)
  1886.       RAY = 7;
  1887.  
  1888.    if (!RAY)
  1889.    {
  1890.       k = 0;
  1891.       LOADPROMPTSCHOICES("make a surface grid");
  1892.       LOADPROMPTSCHOICES("just draw the points");
  1893.       LOADPROMPTSCHOICES("connect the dots (wire frame)");
  1894.       LOADPROMPTSCHOICES("surface fill (colors interpolated)");
  1895.       LOADPROMPTSCHOICES("surface fill (colors not interpolated)");
  1896.       LOADPROMPTSCHOICES("solid fill (bars up from \"ground\")");
  1897.       if(SPHERE)
  1898.       {
  1899.          LOADPROMPTSCHOICES("light source");
  1900.       }
  1901.       else
  1902.       {
  1903.          LOADPROMPTSCHOICES("light source before transformation");
  1904.          LOADPROMPTSCHOICES("light source after transformation");
  1905.       }
  1906.       for (i = 0; i < k; ++i)
  1907.      attributes[i] = 1;
  1908.       helpmode = HELP3DFILL;
  1909.       i = fullscreen_choice(CHOICEHELP,hdg1,NULL,NULL,k,(char far * far *)choices,attributes,
  1910.                   0,0,0,FILLTYPE+1,NULL,NULL,NULL,NULL);
  1911.       helpmode = oldhelpmode;
  1912.       if (i < 0)
  1913.      goto restart_1;
  1914.       FILLTYPE = i-1;
  1915.  
  1916.       if(glassestype)
  1917.       {
  1918.      if(get_funny_glasses_params())
  1919.             goto restart_1;
  1920.          }
  1921.          if (check_mapfile())
  1922.              goto restart_1;
  1923.       }
  1924.    restart_3:
  1925.  
  1926.    if(SPHERE)
  1927.    {
  1928.       k = -1;
  1929.       LOADPROMPTS3D("Longitude start (degrees)");
  1930.       LOADPROMPTS3D("Longitude stop  (degrees)");
  1931.       LOADPROMPTS3D("Latitude start  (degrees)");
  1932.       LOADPROMPTS3D("Latitude stop   (degrees)");
  1933.       LOADPROMPTS3D("Radius scaling factor in pct");
  1934.    }
  1935.    else
  1936.    {
  1937.       k = -1;
  1938.       if (!RAY)
  1939.       {
  1940.          LOADPROMPTS3D("X-axis rotation in degrees");
  1941.          LOADPROMPTS3D("Y-axis rotation in degrees");
  1942.          LOADPROMPTS3D("Z-axis rotation in degrees");
  1943.       }
  1944.       LOADPROMPTS3D("X-axis scaling factor in pct");
  1945.       LOADPROMPTS3D("Y-axis scaling factor in pct");
  1946.    }
  1947.    k = -1;
  1948.    if (!(RAY && !SPHERE))
  1949.    {
  1950.       uvalues[++k].uval.ival   = XROT     ;
  1951.       uvalues[k].type = 'i';
  1952.       uvalues[++k].uval.ival   = YROT     ;
  1953.       uvalues[k].type = 'i';
  1954.       uvalues[++k].uval.ival   = ZROT     ;
  1955.       uvalues[k].type = 'i';
  1956.    }
  1957.    uvalues[++k].uval.ival   = XSCALE    ;
  1958.    uvalues[k].type = 'i';
  1959.  
  1960.    uvalues[++k].uval.ival   = YSCALE    ;
  1961.    uvalues[k].type = 'i';
  1962.  
  1963.    LOADPROMPTS3D("Surface Roughness scaling factor in pct");
  1964.    uvalues[k].type = 'i';
  1965.    uvalues[k].uval.ival = ROUGH     ;
  1966.  
  1967.    LOADPROMPTS3D("'Water Level' (minimum color value)");
  1968.    uvalues[k].type = 'i';
  1969.    uvalues[k].uval.ival = WATERLINE ;
  1970.  
  1971.    if(!RAY)
  1972.    {
  1973.       LOADPROMPTS3D("Perspective distance [1 - 999, 0 for no persp])");
  1974.       uvalues[k].type = 'i';
  1975.       uvalues[k].uval.ival = ZVIEWER     ;
  1976.  
  1977.       LOADPROMPTS3D("X shift with perspective (positive = right)");
  1978.       uvalues[k].type = 'i';
  1979.       uvalues[k].uval.ival = XSHIFT    ;
  1980.    
  1981.       LOADPROMPTS3D("Y shift with perspective (positive = up   )");
  1982.       uvalues[k].type = 'i';
  1983.       uvalues[k].uval.ival = YSHIFT    ;
  1984.    
  1985.       LOADPROMPTS3D("Image non-perspective X adjust (positive = right)");
  1986.       uvalues[k].type = 'i';
  1987.       uvalues[k].uval.ival = xtrans    ;
  1988.    
  1989.       LOADPROMPTS3D("Image non-perspective Y adjust (positive = up)");
  1990.       uvalues[k].type = 'i';
  1991.       uvalues[k].uval.ival = ytrans    ;
  1992.    
  1993.       LOADPROMPTS3D("First transparent color");
  1994.       uvalues[k].type = 'i';
  1995.       uvalues[k].uval.ival = transparent[0];
  1996.    
  1997.       LOADPROMPTS3D("Last transparent color");
  1998.       uvalues[k].type = 'i';
  1999.       uvalues[k].uval.ival = transparent[1];
  2000.    }
  2001.  
  2002.    LOADPROMPTS3D("Randomize Colors      (0 - 7, '0' disables)");
  2003.    uvalues[k].type = 'i';
  2004.    uvalues[k++].uval.ival = RANDOMIZE;
  2005.  
  2006.    if (SPHERE)
  2007.       s = s1;
  2008.    else
  2009.       s = s2;
  2010.  
  2011.    helpmode = HELP3DPARMS;
  2012.    k = fullscreen_prompt(s,k,prompts3d,uvalues,0,NULL);
  2013.    helpmode = oldhelpmode;
  2014.    if (k < 0)
  2015.       goto restart_1;
  2016.  
  2017.    k = 0;
  2018.    if (!(RAY && !SPHERE))
  2019.    {
  2020.       XROT    = uvalues[k++].uval.ival;
  2021.       YROT    = uvalues[k++].uval.ival;
  2022.       ZROT    = uvalues[k++].uval.ival;
  2023.    }
  2024.    XSCALE     = uvalues[k++].uval.ival;
  2025.    YSCALE     = uvalues[k++].uval.ival;
  2026.    ROUGH      = uvalues[k++].uval.ival;
  2027.    WATERLINE  = uvalues[k++].uval.ival;
  2028.    if (!RAY)
  2029.    {
  2030.       ZVIEWER = uvalues[k++].uval.ival;
  2031.    XSHIFT     = uvalues[k++].uval.ival;
  2032.    YSHIFT     = uvalues[k++].uval.ival;
  2033.    xtrans     = uvalues[k++].uval.ival;
  2034.    ytrans     = uvalues[k++].uval.ival;
  2035.    transparent[0] = uvalues[k++].uval.ival;
  2036.    transparent[1] = uvalues[k++].uval.ival;
  2037.    }
  2038.    RANDOMIZE  = uvalues[k++].uval.ival;
  2039.    if (RANDOMIZE >= 7) RANDOMIZE = 7;
  2040.    if (RANDOMIZE <= 0) RANDOMIZE = 0;
  2041.  
  2042.    if ((Targa_Out || ILLUMINE || RAY))
  2043.     if(get_light_params())
  2044.         goto restart_3;
  2045. return(0);
  2046. }
  2047.  
  2048. /* --------------------------------------------------------------------- */
  2049. static int get_light_params()
  2050. {
  2051.    static FCODE hdg[]={"Light Source Parameters"};
  2052.    char far *prompts3d[13];
  2053.    struct fullscreenvalues uvalues[13];
  2054.  
  2055.    int k;
  2056.    int oldhelpmode;
  2057.  
  2058.    /* defaults go here */
  2059.  
  2060.    k = -1;
  2061.  
  2062.    if (ILLUMINE || RAY)
  2063.    {
  2064.    LOADPROMPTS3D("X value light vector");
  2065.    uvalues[k].type = 'i';
  2066.    uvalues[k].uval.ival = XLIGHT    ;
  2067.  
  2068.    LOADPROMPTS3D("Y value light vector");
  2069.    uvalues[k].type = 'i';
  2070.    uvalues[k].uval.ival = YLIGHT    ;
  2071.  
  2072.    LOADPROMPTS3D("Z value light vector");
  2073.    uvalues[k].type = 'i';
  2074.    uvalues[k].uval.ival = ZLIGHT    ;
  2075.  
  2076.         if (!RAY)
  2077.         {
  2078.    LOADPROMPTS3D("Light Source Smoothing Factor");
  2079.    uvalues[k].type = 'i';
  2080.    uvalues[k].uval.ival = LIGHTAVG  ;
  2081.  
  2082.    LOADPROMPTS3D("Ambient");
  2083.    uvalues[k].type = 'i';
  2084.    uvalues[k].uval.ival = Ambient;
  2085.         }
  2086.    }
  2087.  
  2088.    if (Targa_Out && !RAY)
  2089.    {
  2090.     LOADPROMPTS3D("Haze Factor        (0 - 100, '0' disables)");
  2091.     uvalues[k].type = 'i';
  2092.     uvalues[k].uval.ival= haze;
  2093.  
  2094.         if (!Targa_Overlay)
  2095.     check_writefile(light_name,".tga");
  2096.       LOADPROMPTS3D("Targa File Name  (Assume .tga)");
  2097.     uvalues[k].type = 's';
  2098.     strcpy(uvalues[k].uval.sval,light_name);
  2099.  
  2100.       LOADPROMPTS3D("Back Ground Color (0 - 255)");
  2101.       uvalues[k].type = '*';
  2102.  
  2103.       LOADPROMPTS3D("   Red");
  2104.       uvalues[k].type = 'i';
  2105.       uvalues[k].uval.ival = (int)back_color[0];
  2106.  
  2107.       LOADPROMPTS3D("   Green");
  2108.       uvalues[k].type = 'i';
  2109.       uvalues[k].uval.ival = (int)back_color[1];
  2110.  
  2111.       LOADPROMPTS3D("   Blue");
  2112.       uvalues[k].type = 'i';
  2113.       uvalues[k].uval.ival = (int)back_color[2];
  2114.  
  2115.       LOADPROMPTS3D("Overlay Targa File? (Y/N)");
  2116.       uvalues[k].type = 'y';
  2117.       uvalues[k].uval.ch.val = Targa_Overlay;
  2118.  
  2119.    }
  2120.  
  2121.    LOADPROMPTS3D("");
  2122.  
  2123.    oldhelpmode = helpmode;
  2124.    helpmode = HELP3DLIGHT;
  2125.    k = fullscreen_prompt(hdg,k,prompts3d,uvalues,0,NULL);
  2126.    helpmode = oldhelpmode;
  2127.    if (k < 0)
  2128.       return(-1);
  2129.  
  2130.    k = 0;
  2131.    if (ILLUMINE)
  2132.    {
  2133.       XLIGHT   = uvalues[k++].uval.ival;
  2134.       YLIGHT   = uvalues[k++].uval.ival;
  2135.       ZLIGHT   = uvalues[k++].uval.ival;
  2136.       if (!RAY)
  2137.         {
  2138.       LIGHTAVG = uvalues[k++].uval.ival;
  2139.       Ambient  = uvalues[k++].uval.ival;
  2140.       if (Ambient >= 100) Ambient = 100;
  2141.       if (Ambient <= 0) Ambient = 0;
  2142.         }
  2143.    }
  2144.  
  2145.    if (Targa_Out && !RAY)
  2146.    {
  2147.     haze  =  uvalues[k++].uval.ival;
  2148.     if (haze >= 100) haze = 100;
  2149.     if (haze <= 0) haze = 0;
  2150.         strcpy(light_name,uvalues[k++].uval.sval);
  2151.         /* In case light_name conflicts with an existing name it is checked
  2152.             again in line3d */
  2153.         k++;
  2154.         back_color[0] = (char)(uvalues[k++].uval.ival % 255);
  2155.         back_color[1] = (char)(uvalues[k++].uval.ival % 255);
  2156.         back_color[2] = (char)(uvalues[k++].uval.ival % 255);
  2157.         Targa_Overlay = uvalues[k].uval.ch.val;
  2158.    }
  2159.    return(0);
  2160. }
  2161.  
  2162. /* --------------------------------------------------------------------- */
  2163.  
  2164.  
  2165. static int check_mapfile()
  2166. {
  2167.    int askflag = 0;
  2168.    int i,oldhelpmode;
  2169.    if(dontreadcolor)
  2170.       return(0);
  2171.    strcpy(temp1,"*");
  2172.    if (mapset)
  2173.       strcpy(temp1,MAP_name);
  2174.    if (!(glassestype == 1 || glassestype == 2))
  2175.       askflag = 1;
  2176.    else
  2177.       merge_pathnames(temp1,funnyglasses_map_name,0);
  2178.    
  2179.    for(;;) {
  2180.       if (askflag) {
  2181.          static FCODE msg[] = {"\
  2182. Enter name of .MAP file to use,\n\
  2183. or '*' to use palette from the image to be loaded."};
  2184.      oldhelpmode = helpmode;
  2185.      helpmode = -1;
  2186.      i = field_prompt(0,msg,NULL,temp1,60,NULL);
  2187.      helpmode = oldhelpmode;
  2188.      if (i < 0)
  2189.         return(-1);
  2190.          if (temp1[0] == '*') {
  2191.             mapset = 0;
  2192.             break;
  2193.          }
  2194.       }
  2195.       memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  2196.       i = ValidateLuts(temp1);
  2197.       memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  2198.       if (i != 0) { /* Oops, somethings wrong */
  2199.          askflag = 1;
  2200.          continue;
  2201.          }
  2202.       mapset = 1;
  2203.       merge_pathnames(MAP_name,temp1,0);
  2204.       break;
  2205.       }
  2206.    return(0);
  2207. }
  2208.  
  2209. static int get_funny_glasses_params()
  2210. {
  2211.    static FCODE hdg[]={"Funny Glasses Parameters"};
  2212.    char far *prompts3d[10];
  2213.  
  2214.    struct fullscreenvalues uvalues[10];
  2215.  
  2216.    int k;
  2217.    int oldhelpmode;
  2218.  
  2219.    /* defaults */
  2220.    if(ZVIEWER == 0)
  2221.       ZVIEWER = 150;
  2222.    if(eyeseparation == 0)
  2223.    {
  2224.       if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D)
  2225.       {
  2226.      eyeseparation =  2;
  2227.      xadjust       = -2;
  2228.       }
  2229.       else
  2230.       {
  2231.      eyeseparation =  3;
  2232.      xadjust       =  0;
  2233.       }
  2234.    }
  2235.  
  2236.    if(glassestype == 1)
  2237.       strcpy(funnyglasses_map_name,Glasses1Map);
  2238.    else if(glassestype == 2)
  2239.    {
  2240.       if(FILLTYPE == -1)
  2241.      strcpy(funnyglasses_map_name,"grid.map");
  2242.       else
  2243.       {
  2244.      strcpy(funnyglasses_map_name,Glasses1Map);
  2245.      funnyglasses_map_name[7] = '2';
  2246.       }
  2247.    }
  2248.  
  2249.    k = -1;
  2250.    LOADPROMPTS3D("Interocular distance (as % of screen)");
  2251.    uvalues[k].type = 'i';
  2252.    uvalues[k].uval.ival= eyeseparation;
  2253.  
  2254.    LOADPROMPTS3D("Convergence adjust (positive = spread greater)");
  2255.    uvalues[k].type = 'i';
  2256.    uvalues[k].uval.ival = xadjust;
  2257.  
  2258.    LOADPROMPTS3D("Left  red image crop (% of screen)");
  2259.    uvalues[k].type = 'i';
  2260.    uvalues[k].uval.ival = red_crop_left;
  2261.  
  2262.    LOADPROMPTS3D("Right red image crop (% of screen)");
  2263.    uvalues[k].type = 'i';
  2264.    uvalues[k].uval.ival = red_crop_right;
  2265.  
  2266.    LOADPROMPTS3D("Left  blue image crop (% of screen)");
  2267.    uvalues[k].type = 'i';
  2268.    uvalues[k].uval.ival = blue_crop_left;
  2269.  
  2270.    LOADPROMPTS3D("Right blue image crop (% of screen)");
  2271.    uvalues[k].type = 'i';
  2272.    uvalues[k].uval.ival = blue_crop_right;
  2273.  
  2274.    LOADPROMPTS3D("Red brightness factor (%)");
  2275.    uvalues[k].type = 'i';
  2276.    uvalues[k].uval.ival = red_bright;
  2277.  
  2278.    LOADPROMPTS3D("Blue brightness factor (%)");
  2279.    uvalues[k].type = 'i';
  2280.    uvalues[k].uval.ival = blue_bright;
  2281.  
  2282.    if(glassestype == 1 || glassestype == 2)
  2283.    {
  2284.       LOADPROMPTS3D("Map File name");
  2285.       uvalues[k].type = 's';
  2286.       strcpy(uvalues[k].uval.sval,funnyglasses_map_name);
  2287.    }
  2288.  
  2289.    oldhelpmode = helpmode;
  2290.    helpmode = HELP3DGLASSES;
  2291.    k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
  2292.    helpmode = oldhelpmode;
  2293.    if (k < 0)
  2294.       return(-1);
  2295.  
  2296.    k = 0;
  2297.    eyeseparation   =  uvalues[k++].uval.ival;
  2298.    xadjust       =  uvalues[k++].uval.ival;
  2299.    red_crop_left   =  uvalues[k++].uval.ival;
  2300.    red_crop_right  =  uvalues[k++].uval.ival;
  2301.    blue_crop_left  =  uvalues[k++].uval.ival;
  2302.    blue_crop_right =  uvalues[k++].uval.ival;
  2303.    red_bright       =  uvalues[k++].uval.ival;
  2304.    blue_bright       =  uvalues[k++].uval.ival;
  2305.  
  2306.    if(glassestype == 1 || glassestype == 2)
  2307.       strcpy(funnyglasses_map_name,uvalues[k].uval.sval);
  2308.    return(0);
  2309. }
  2310.  
  2311. void setbailoutformula(enum bailouts test) {
  2312.  
  2313.    switch(test) {
  2314.      case Mod:
  2315.      default:{
  2316.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2317.            floatbailout = (int (near *)(void))asmfpMODbailout;
  2318.          else
  2319.            floatbailout = (int (near *)(void))fpMODbailout;
  2320.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2321.            longbailout = (int (near *)(void))asm386lMODbailout;
  2322.          else
  2323.            longbailout = (int (near *)(void))asmlMODbailout;
  2324.          bignumbailout = (int (near *)(void))bnMODbailout;
  2325.          bigfltbailout = (int (near *)(void))bfMODbailout;
  2326.          break;}
  2327.      case Real: {
  2328.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2329.            floatbailout = (int (near *)(void))asmfpREALbailout;
  2330.          else
  2331.            floatbailout = (int (near *)(void))fpREALbailout;
  2332.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2333.            longbailout = (int (near *)(void))asm386lREALbailout;
  2334.          else
  2335.            longbailout = (int (near *)(void))asmlREALbailout;
  2336.          bignumbailout = (int (near *)(void))bnREALbailout;
  2337.          bigfltbailout = (int (near *)(void))bfREALbailout;
  2338.          break;}
  2339.      case Imag:{
  2340.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2341.            floatbailout = (int (near *)(void))asmfpIMAGbailout;
  2342.          else
  2343.            floatbailout = (int (near *)(void))fpIMAGbailout;
  2344.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2345.            longbailout = (int (near *)(void))asm386lIMAGbailout;
  2346.          else
  2347.            longbailout = (int (near *)(void))asmlIMAGbailout;
  2348.          bignumbailout = (int (near *)(void))bnIMAGbailout;
  2349.          bigfltbailout = (int (near *)(void))bfIMAGbailout;
  2350.          break;}
  2351.      case Or:{
  2352.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2353.            floatbailout = (int (near *)(void))asmfpORbailout;
  2354.          else
  2355.            floatbailout = (int (near *)(void))fpORbailout;
  2356.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2357.            longbailout = (int (near *)(void))asm386lORbailout;
  2358.          else
  2359.            longbailout = (int (near *)(void))asmlORbailout;
  2360.          bignumbailout = (int (near *)(void))bnORbailout;
  2361.          bigfltbailout = (int (near *)(void))bfORbailout;
  2362.          break;}
  2363.      case And:{
  2364.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2365.            floatbailout = (int (near *)(void))asmfpANDbailout;
  2366.          else
  2367.            floatbailout = (int (near *)(void))fpANDbailout;
  2368.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2369.            longbailout = (int (near *)(void))asm386lANDbailout;
  2370.          else
  2371.            longbailout = (int (near *)(void))asmlANDbailout;
  2372.          bignumbailout = (int (near *)(void))bnANDbailout;
  2373.          bigfltbailout = (int (near *)(void))bfANDbailout;
  2374.          break;}
  2375.    }
  2376. }
  2377.